package com.h3c.nem.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eos.common.util.IdWorker;
import com.h3c.nem.cache.TbOfferWorkerCache;
import com.h3c.nem.client.AbilityClient;
import com.h3c.nem.config.properties.TbOfferWorkerProperties;
import com.h3c.nem.dto.AttachmentFileInfo;
import com.h3c.nem.dto.LoginUserDTO;
import com.h3c.nem.dto.TbOfferAttachmentDTO;
import com.h3c.nem.dto.beisen.OcrDTO;
import com.h3c.nem.entity.SdNoticeRecord;
import com.h3c.nem.entity.TbOfferAttachment;
import com.h3c.nem.entity.TbOfferWorker;
import com.h3c.nem.enums.IdTypeEnum;
import com.h3c.nem.mapper.TbOfferAttachmentMapper;
import com.h3c.nem.mapstruct.TbOfferAttachmentMapstruct;
import com.h3c.nem.service.*;
import com.h3c.nem.utils.AppBusinessException;
import com.h3c.nem.utils.BusiEnumDefine;
import com.h3c.nem.utils.CommonUtil;
import com.h3c.nem.vo.TbOfferAttachmentVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * offer附件图片实现类
 *
 * @author chenyifan
 * @since 2022-06-02 17:14:08
 */
@Service
public class TbOfferAttachmentServiceImpl extends ServiceImpl<TbOfferAttachmentMapper, TbOfferAttachment> implements ITbOfferAttachmentService {

    @Resource
    @Lazy
    private ITbOfferWorkerService offerWorkerService;

    @Resource
    private BeiSenService beiSenService;

    @Resource
    private TbOfferWorkerProperties workerProperties;

    @Resource
    private AbilityClient abilityClient;

    @Resource
    private CommService commService;

    @Resource
    private ITbApprovalRecordService approvalRecordService;

    @Resource
    private ITbWorkerExperienceService iTbWorkerExperienceService;

    @Value("${upload.cardimage.url}")
    private String uploadCardImageUrl;
    @Value("${ocr.flag}")
    private String ocrFlag;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, String> saveAppendInfo(TbOfferAttachmentDTO attachmentDTO) {
        String userId = CommonUtil.getActivUser().getUserId();
        TbOfferWorker offerWorker = offerWorkerService.getById(userId);
        offerWorkerService.updateById(offerWorker
                .setWorkerId(userId)
                .setUpdateTime(new Date())
                .setUpdatorInfo(userId)
                .setLastLeaveDate(attachmentDTO.getLastLeaveDate()));
        remove(new QueryWrapper<TbOfferAttachment>().lambda()
                .eq(TbOfferAttachment::getWorkerId, userId)
        );
        OcrDTO ocrResult = new OcrDTO();
        List<AttachmentFileInfo> idCardList = attachmentDTO.getAttachmentFileInfoList().stream().filter(s -> s.getFileType().equals(TbOfferAttachment.ID_CARD_FRONT)).collect(Collectors.toList());
        if ("1".equals(ocrFlag) && offerWorker.getCertType().equals(IdTypeEnum.ID_CARD)) {
            for (AttachmentFileInfo idCard : idCardList) {
                JSONObject result = abilityClient.downloadFile(idCard.getFileId(), idCard.getFileName(), workerProperties.getDownloadSfsAccount());
                String file = result.getJSONObject("data").getString("file");
                OcrDTO ocrDTO = beiSenService.idCardOcrImageBase64(file);
                if (Objects.isNull(ocrDTO) || StringUtils.isEmpty(ocrDTO.getName()) || ocrDTO.getBirth()==null || StringUtils.isEmpty(ocrDTO.getSex())) {
                    throw new AppBusinessException("身份证识别失败，请上传清晰的人像面照片");
                }
                BeanUtils.copyProperties(ocrDTO, ocrResult);
                if (StringUtils.hasText(ocrDTO.getIdNum())) {
                    if (!ocrDTO.getIdNum().equals(offerWorker.getCertNo())) {
                        throw new AppBusinessException("身份证照片与身份证信息不符");
                    }
                }
            }
        }
        List<TbOfferAttachment> offerAttachments = TbOfferAttachmentMapstruct.INSTANCE.dtoList2EntityList(attachmentDTO.getAttachmentFileInfoList());
        offerAttachments.forEach(s ->
                s.setUploadTime(new Date())
                .setAttachmentId(IdWorker.nextId() + "")
                .setWorkerId(userId));
        saveBatch(offerAttachments);
        HashMap<String, String> result = new HashMap<>(3);
        if ("1".equals(ocrFlag) && offerWorker.getCertType().equals(IdTypeEnum.ID_CARD)) {
            if (!ocrResult.getName().equals(offerWorker.getWorkerName())) {
                result.put(OcrDTO.Fields.name.name(), ocrResult.getName());
            }
            if (!ocrResult.getBirth().equals(DateUtil.format(offerWorker.getBirthday(), "yyyy/M/d"))) {
                result.put(OcrDTO.Fields.birth.name(), ocrResult.getBirth());
            }
            if (!ocrResult.getSex().equals(offerWorker.getSex())) {
                result.put(OcrDTO.Fields.sex.name(), ocrResult.getSex());
            }
//        if (!offerWorker.getNation().contains(ocrResult.getNation())) {
//            result.put(OcrDTO.Fields.nation.name(), ocrResult.getNation());
//        }
        }
        //把填的离职日期更新到工作经历结束日期为空的数据上
        iTbWorkerExperienceService.setWorkExpWithoutEnd(attachmentDTO.getLastLeaveDate(), userId);
        if(result.keySet().size()>0){
            update(null, new LambdaUpdateWrapper<TbOfferAttachment>()
                    .set(TbOfferAttachment::getAlreadySave, false)
                    .eq(TbOfferAttachment::getWorkerId, userId)
                    .eq(TbOfferAttachment::getFileType, 4)
            );
        }else{
            TbOfferWorkerCache.updateFillStatus(userId, TbOfferWorkerCache.ATTACHMENT);
        }
        return result;
    }

    @Override
    public Map<String, Object> showAppendInfo() {
        List<TbOfferAttachment> attachments = list(new QueryWrapper<TbOfferAttachment>().lambda()
                .eq(TbOfferAttachment::getWorkerId, CommonUtil.getActivUser().getUserId())
        );
        HashMap<String, Object> result = new HashMap<>(2);
        result.put("lastLeaveDate", DateUtil.format(offerWorkerService.getById(CommonUtil.getActivUser().getUserId()).getLastLeaveDate(),
                "yyyy-MM-dd"));
        result.put("attachmentFileInfoList", TbOfferAttachmentMapstruct.INSTANCE.entityList2VOList(attachments));
        return result;
    }

    @Override
    public String getOfferWorkerFileId(Integer fileType, String workerId) {
        QueryWrapper<TbOfferAttachment> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbOfferAttachment::getFileType, fileType)
                .eq(TbOfferAttachment::getWorkerId, workerId);
        List<TbOfferAttachment> list = list(queryWrapper);
        if (!list.isEmpty()) {
            TbOfferAttachment tbOfferAttachment = list.get(0);
            return tbOfferAttachment.getFileId();
        } else {
            return "";
        }
    }

    @Override
    public Map<String, String> getOfferWorkerFileIdList(Integer fileType, List<String> workerId) {
        if (CollectionUtils.isEmpty(workerId)) {
            return new HashMap<>();
        }
        QueryWrapper<TbOfferAttachment> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbOfferAttachment::getFileType, fileType)
                .in(TbOfferAttachment::getWorkerId, workerId);
        List<TbOfferAttachment> list = list(queryWrapper);
        if (!list.isEmpty()) {
            return list.stream().collect(Collectors.groupingBy(TbOfferAttachment::getWorkerId,
                    Collectors.collectingAndThen(Collectors.toList(),
                            o -> o.stream().map(TbOfferAttachment::getFileId).findFirst().orElse(""))));
        } else {
            return new HashMap<>();
        }
    }

    @Override
    public List<TbOfferAttachmentVO> getOfferAttachment(Integer fileType, String workerId) {
        QueryWrapper<TbOfferAttachment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("worker_id", workerId);
        if (fileType != null) {
            queryWrapper.eq("file_type", fileType);
        }
        List<TbOfferAttachment> list = list(queryWrapper);
        return TbOfferAttachmentMapstruct.INSTANCE.entityList2VOList(list);
    }

    @Override
    public void updateAvatarAttachmentInfo(String avatarId, String avatarName) {
        TbOfferAttachment oldAvatarAttachment = getOne(new QueryWrapper<TbOfferAttachment>().lambda()
                .eq(TbOfferAttachment::getWorkerId, CommonUtil.getActivUser().getUserId())
                .eq(TbOfferAttachment::getFileType, TbOfferAttachment.WORK_CARD_PHOTO)
        );
        if (oldAvatarAttachment.getApprovalStatus().equals(TbOfferAttachment.AVATAR_PASS)) {
            throw new AppBusinessException("头像已审核通过无法修改");
        }
        oldAvatarAttachment
                .setFileId(avatarId)
                .setUploadTime(new Date())
                .setFileName(avatarName)
                .setApprovalStatus(TbOfferAttachment.AVATAR_REVIEW);
        updateById(oldAvatarAttachment);
    }

    /**
     * 更新人员工卡照片状态
     *
     * @Param: attachmentId 附件ID
     * @Param: phoneNo 电话号码
     * @Param: isPass 是否通过
     * @Param: rejectReason 拒绝意见
     * @Author: h24002
     * @Date: 2022/6/24
     */
    @Override
    public Boolean updateWorkerCardImageStatus(String attachmentId, String phoneNo, Boolean isPass, String rejectReason) {
        //附件
        if (!StringUtils.hasText(attachmentId)) {
            throw new AppBusinessException("请传入手机号");
        }
        //驳回要有手机号
        if (!isPass && !StringUtils.hasText(phoneNo)) {
            throw new AppBusinessException("请传入手机号");
        }

        TbOfferAttachment info = this.getById(attachmentId);
        if (info == null) {
            throw new AppBusinessException("不存在此记录");
        }
        rejectReason = StringUtils.hasText(rejectReason) ? rejectReason : "照片不合规，请重新上传";
        if (isPass) {
            info.setApprovalStatus(2);
            info.setRejectReason("");
        } else {
            info.setApprovalStatus(3);
            info.setRejectReason(rejectReason);
        }

        Boolean isOK = this.updateById(info);
        if (isOK) {
            LoginUserDTO userDTO = commService.getLoginUserDTO();
            if (!isPass) {
                //拒绝发送短信
                SdNoticeRecord sdNoticeRecord = new SdNoticeRecord();
                sdNoticeRecord.setNoticeId(IdWorker.nextId() + "");
                sdNoticeRecord.setFlowId("-1");
                sdNoticeRecord.setApplyUserId(userDTO.getAccount());
                sdNoticeRecord.setNoticeType(BusiEnumDefine.NOTICE_TYPE_SMS);
                sdNoticeRecord.setTargetPhone(phoneNo);
                sdNoticeRecord.setNoticeTitle("更改工卡照片");
                sdNoticeRecord.setNoticeContent("您的工卡照片因 " + rejectReason + " 审核未通过，请按照要求重新上传工卡照片，修改工卡照片地址链接：" + uploadCardImageUrl + "，点击头像下方文字即可替换工卡照片");
                sdNoticeRecord.setCreateTime(new Date());
                commService.sendMessage(sdNoticeRecord);
            }

            //再插入消息中心数据
            approvalRecordService.saveRecord(info.getWorkerId(), BusiEnumDefine.APPROVAL_TYPE_CARD_IMAGE, userDTO.getUserId(), userDTO.getUserName(), rejectReason, isPass ? 1 : 2);
        }
        return isOK;
    }

}

